package uk.co.q3c.deplan.client.ui.view;

import java.util.logging.Logger;

import uk.co.q3c.deplan.client.Orchestrator;
import uk.co.q3c.deplan.client.domain.DomainObject;
import uk.co.q3c.deplan.client.ui.presenter.HomePresenter;
import uk.co.q3c.deplan.client.ui.presenter.Presenter;
import uk.co.q3c.deplan.client.ui.presenter.ProjectPresenter;
import uk.co.q3c.deplan.client.ui.presenter.ProjectTaskPresenter;
import uk.co.q3c.deplan.client.ui.presenter.ProjectsPresenter;
import uk.co.q3c.deplan.client.ui.presenter.ResourcesPresenter;
import uk.co.q3c.deplan.client.util.HistoryToken;
import uk.co.q3c.deplan.client.util.HistoryTokenRecord;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Command;

public class ScreenPresenter implements ValueChangeHandler<String> {
	protected static final Logger logger = Logger.getLogger(ScreenPresenter.class.getName());
	private final ScreenView screenView;
	private Q3CoreView currentCoreView;

	public Q3CoreView getCurrentCoreView() {
		return currentCoreView;
	}

	public ScreenPresenter(ScreenView screenView) {
		super();
		this.screenView = screenView;
	}

	public Command cmdOpenResourcesView = new Command() {
		public void execute() {
			resourcesView();
		}
	};

	public Command cmdOpenProjectsView = new Command() {
		public void execute() {
			projectsView();
		}
	};

	public Command cmdOpenHomeView = new Command() {
		public void execute() {
			homeView();
		}
	};

	/**
	 * Switches from current view in the core panel to the view provided. The old view has its presenter set to null in order to release it.
	 * The view itself is cached by the {@link ViewManager} because it is expensive to create.<br>
	 * <br>
	 * The new view is initialised {@link Q3CoreView#init()) if has not been already, and reset {@link Q3CoreView#reset()} if it has been
	 * returned
	 * 
	 * @param newView
	 */
	public void changeViewTo(Q3CoreView newView) {
		// get the current view and release its presenter

		if (currentCoreView != null) {
			currentCoreView.setPresenter(null);
		}
		// if the new view is initialised, just reset it, otherwise initialise
		// it. (If not initialised this it has just been created as opposed to
		// being returned from cache)
		if (newView.isInitialised()) {
			newView.reset();
		} else {
			newView.init();
		}
		// create a presenter for the new view
		Presenter presenter = presenter(newView);
		// cross-refer presenter and view
		presenter.setView(newView);
		newView.setPresenter(presenter(newView));
		// set the new view into the screen core panel
		screenView.setCorePanel(newView);
		currentCoreView = newView;
		// update history
		Orchestrator.viewManager()
				.newHistoryItem(newView, false);

	}

	private Presenter presenter(Q3CoreView newView) {
		switch (newView.viewTag()) {
		case HomeView:
			return new HomePresenter();
		case ProjectsView:
			return new ProjectsPresenter();
		case AbstractTaskView:
			return new ProjectTaskPresenter();
		case ResourcesView:
			return new ResourcesPresenter();
		case ProjectView:
			return new ProjectPresenter();
		default:
			logger.severe("Presenter not defined for " + newView.viewTag());
			return null;
		}
	}

	/**
	 */
	public void resourcesView() {
		Q3CoreView view = Orchestrator.viewManager()
				.view(Viewtags.ResourcesView);
		changeViewTo(view);
	}

	/**
	 */
	public void projectsView() {
		Q3CoreView view = Orchestrator.viewManager()
				.view(Viewtags.ProjectsView);
		changeViewTo(view);
	}

	public void homeView() {
		Q3CoreView view = Orchestrator.viewManager()
				.view(Viewtags.HomeView);
		changeViewTo(view);
	}

	/**
	 * 
	 */
	public void onValueChange(ValueChangeEvent<String> event) {
		String token = event.getValue();

		// Parse the token to establish view and object
		HistoryTokenRecord htr = HistoryToken.parseToken(token);
		changeViewTo(Orchestrator.viewManager()
				.view(htr.viewName));

	}

	public void prepareMenus() {
		screenView.setResourcesMICommand(cmdOpenResourcesView);
		screenView.setProjectsMICommand(cmdOpenProjectsView);
	}

	public void changeViewTo(Viewtags viewTag) {
		changeViewTo(Orchestrator.viewManager()
				.view(viewTag));

	}

	public void setObjectInView(DomainObject dob) {
		currentCoreView.getPresenter()
				.setObjectInView(dob);

	}
}
